// MainDlg.cpp : implementation of the CMainDlg class
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"

#include "aboutdlg.h"
#include "MainDlg.h"

#include <winioctl.h>


#define SYMBOL_DEVICE_NAME L"\\\\.\\HelloDriver"

#define IOCTROL_CODE1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_DPC_TEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_THREAD_TEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)

HANDLE g_hDevice = INVALID_HANDLE_VALUE;

BOOL CMainDlg::PreTranslateMessage(MSG* pMsg)
{
	return CWindow::IsDialogMessage(pMsg);
}

BOOL CMainDlg::OnIdle()
{
	UIUpdateChildWindows();
	return FALSE;
}

LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	// center the dialog on the screen
	CenterWindow();

	// set icons
	HICON hIcon = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));
	SetIcon(hIcon, TRUE);
	HICON hIconSmall = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON));
	SetIcon(hIconSmall, FALSE);

	// register object for message filtering and idle updates
	CMessageLoop* pLoop = _Module.GetMessageLoop();
	ATLASSERT(pLoop != NULL);
	pLoop->AddMessageFilter(this);
	pLoop->AddIdleHandler(this);

	UIAddChildWindowContainer(m_hWnd);

	return TRUE;
}

LRESULT CMainDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	// unregister message filtering and idle updates
	CMessageLoop* pLoop = _Module.GetMessageLoop();
	ATLASSERT(pLoop != NULL);
	pLoop->RemoveMessageFilter(this);
	pLoop->RemoveIdleHandler(this);

	return 0;
}

LRESULT CMainDlg::OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	CAboutDlg dlg;
	dlg.DoModal();
	return 0;
}

LRESULT CMainDlg::OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	// TODO: Add validation code 
	CloseDialog(wID);
	return 0;
}

LRESULT CMainDlg::OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	CloseDialog(wID);
	return 0;
}

void CMainDlg::CloseDialog(int nVal)
{
	DestroyWindow();
	::PostQuitMessage(nVal);
}

LRESULT CMainDlg::OnBnClickedBtnCreate(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if (g_hDevice != INVALID_HANDLE_VALUE )
	{
		CloseHandle(g_hDevice);
		g_hDevice = INVALID_HANDLE_VALUE;
	}

	g_hDevice = CreateFile(SYMBOL_DEVICE_NAME, FILE_READ_ACCESS| FILE_WRITE_ACCESS, NULL, 
		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);

	if (g_hDevice == INVALID_HANDLE_VALUE)
	{
		MessageBox(_T("Open Device Failure"), _T("Failure"), MB_ICONINFORMATION);
		return 0;
	}

	//MessageBox(_T("Open Device Success"), _T("Success"), MB_ICONINFORMATION);
	return 0;
}

LRESULT CMainDlg::OnBnClickedBtnClose(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if (g_hDevice != INVALID_HANDLE_VALUE)
	{
		CloseHandle(g_hDevice);
		g_hDevice = INVALID_HANDLE_VALUE;
	}

	return 0;
}

LRESULT CMainDlg::OnBnClickedBtnRead(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if (g_hDevice == INVALID_HANDLE_VALUE)
		return 0;

	char buffer[256] = {};
	DWORD nReaded = 0;
	BOOL bResult = ReadFile(g_hDevice, buffer, 255, &nReaded, NULL);

	StringCbPrintfA(buffer, 256, "bResult = %d, nReaded = %d", bResult, nReaded);
	MessageBoxA(m_hWnd, buffer, "Info", MB_ICONINFORMATION);
	return 0;
}

LRESULT CMainDlg::OnBnClickedBtnWrite(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if (g_hDevice == INVALID_HANDLE_VALUE)
		return 0;

	char buffer[256] = {};
	DWORD nWrited = 0;
	BOOL bResult = WriteFile(g_hDevice, buffer, 255, &nWrited, NULL);

	StringCbPrintfA(buffer, 256, "bResult = %d, nWrited = %d", bResult, nWrited);
	MessageBoxA(m_hWnd, buffer, "Info", MB_ICONINFORMATION);
	return 0;
}

LRESULT CMainDlg::OnBnClickedBtnIocontrol(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if (g_hDevice == INVALID_HANDLE_VALUE)
		return 0;

	char inBuffer[256] = {};
	char outBuffer[256] = {};
	DWORD outSize = 0;
	
	BOOL bResult = DeviceIoControl(g_hDevice, IOCTROL_CODE1, inBuffer, 202, outBuffer, 250, &outSize, NULL );

	StringCbPrintfA(inBuffer, 256, "bResult = %d, outSize = %d", bResult, outSize);
	MessageBoxA(m_hWnd, inBuffer, "Info", MB_ICONINFORMATION);
	return 0;
}

LRESULT CMainDlg::OnBnClickedButton1(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if (g_hDevice == INVALID_HANDLE_VALUE)
		return 0;

	char inBuffer[256] = {};
	char outBuffer[256] = {};
	DWORD outSize = 0;

	BOOL bResult = DeviceIoControl(g_hDevice, IOCTL_DPC_TEST, inBuffer, 202, outBuffer, 250, &outSize, NULL );

	//StringCbPrintfA(inBuffer, 256, "bResult = %d, outSize = %d", bResult, outSize);
	//MessageBoxA(m_hWnd, inBuffer, "Info", MB_ICONINFORMATION);


	return 0;
}

LRESULT CMainDlg::OnBnClickedButton2(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if (g_hDevice == INVALID_HANDLE_VALUE)
		return 0;

	char inBuffer[256] = {};
	char outBuffer[256] = {};
	DWORD outSize = 0;

	BOOL bResult = DeviceIoControl(g_hDevice, IOCTL_THREAD_TEST, inBuffer, 202, outBuffer, 250, &outSize, NULL );

	return 0;
}
